import { useState, useCallback } from 'react';
import { message } from 'antd';

/**
 * 统一错误处理类型
 */
export interface ErrorInfo {
  message: string;
  code?: string | number;
  details?: any;
  timestamp: number;
}

/**
 * 统一错误处理Hook
 * 提供全局错误处理、错误状态管理和错误恢复机制
 */
export const useErrorHandler = () => {
  const [error, setError] = useState<ErrorInfo | null>(null);
  const [hasError, setHasError] = useState(false);

  /**
   * 处理错误的核心方法
   * @param error - 错误对象或错误消息
   * @param showMessage - 是否显示错误提示，默认为true
   * @param customMessage - 自定义错误消息
   */
  const handleError = useCallback((
    error: any,
    showMessage: boolean = true,
    customMessage?: string
  ) => {
    // 对被标记为静默的错误（如OPTIONS预检）不展示提示
    const isSilent = !!error?.__silent;
    if (isSilent) {
      showMessage = false;
    }
    let errorInfo: ErrorInfo;

    // 解析不同类型的错误
    if (typeof error === 'string') {
      errorInfo = {
        message: error,
        timestamp: Date.now()
      };
    } else if (error?.response) {
      // HTTP错误响应
      const { status, data } = error.response;
      errorInfo = {
        message: customMessage || data?.message || `请求失败 (${status})`,
        code: status,
        details: data,
        timestamp: Date.now()
      };
    } else if (error?.message) {
      // 标准Error对象
      errorInfo = {
        message: customMessage || error.message,
        code: error.code,
        details: error,
        timestamp: Date.now()
      };
    } else {
      // 未知错误
      errorInfo = {
        message: customMessage || '发生未知错误',
        details: error,
        timestamp: Date.now()
      };
    }

    setError(errorInfo);
    setHasError(true);

    // 显示错误提示
    if (showMessage) {
      message.error(errorInfo.message);
    }

    // 记录错误日志
    console.error('Error handled:', errorInfo);

    return errorInfo;
  }, []);

  /**
   * 清除错误状态
   */
  const clearError = useCallback(() => {
    setError(null);
    setHasError(false);
  }, []);

  /**
   * 重试机制包装器
   * @param asyncFn - 异步函数
   * @param maxRetries - 最大重试次数，默认为3
   * @param retryDelay - 重试延迟时间(ms)，默认为1000
   */
  const withRetry = useCallback(async <T>(
    asyncFn: () => Promise<T>,
    maxRetries: number = 3,
    retryDelay: number = 1000
  ): Promise<T> => {
    let lastError: any;
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        clearError();
        return await asyncFn();
      } catch (error) {
        lastError = error;
        
        if (attempt === maxRetries) {
          handleError(error, true, `操作失败，已重试${maxRetries}次`);
          throw error;
        }
        
        // 等待后重试
        await new Promise(resolve => setTimeout(resolve, retryDelay * attempt));
      }
    }
    
    throw lastError;
  }, [handleError, clearError]);

  return {
    error,
    hasError,
    handleError,
    clearError,
    withRetry,
  };
};

/**
 * 全局Loading状态管理Hook
 * 提供统一的Loading状态管理和自动清理机制
 */
export const useLoadingState = () => {
  const [loadingStates, setLoadingStates] = useState<Record<string, boolean>>({});
  const [globalLoading, setGlobalLoading] = useState(false);

  /**
   * 设置特定操作的Loading状态
   * @param key - Loading状态的唯一标识
   * @param loading - Loading状态
   */
  const setLoading = useCallback((key: string, loading: boolean) => {
    setLoadingStates(prev => ({
      ...prev,
      [key]: loading
    }));
  }, []);

  /**
   * 获取特定操作的Loading状态
   * @param key - Loading状态的唯一标识
   */
  const getLoading = useCallback((key: string): boolean => {
    return loadingStates[key] || false;
  }, [loadingStates]);

  /**
   * 清除特定操作的Loading状态
   * @param key - Loading状态的唯一标识
   */
  const clearLoading = useCallback((key: string) => {
    setLoadingStates(prev => {
      const newState = { ...prev };
      delete newState[key];
      return newState;
    });
  }, []);

  /**
   * 清除所有Loading状态
   */
  const clearAllLoading = useCallback(() => {
    setLoadingStates({});
    setGlobalLoading(false);
  }, []);

  /**
   * 异步操作包装器，自动管理Loading状态
   * @param key - Loading状态的唯一标识
   * @param asyncFn - 异步函数
   */
  const withLoading = useCallback(async <T>(
    key: string,
    asyncFn: () => Promise<T>
  ): Promise<T> => {
    try {
      setLoading(key, true);
      return await asyncFn();
    } finally {
      setLoading(key, false);
    }
  }, [setLoading]);

  /**
   * 全局Loading包装器
   * @param asyncFn - 异步函数
   */
  const withGlobalLoading = useCallback(async <T>(
    asyncFn: () => Promise<T>
  ): Promise<T> => {
    try {
      setGlobalLoading(true);
      return await asyncFn();
    } finally {
      setGlobalLoading(false);
    }
  }, []);

  // 计算是否有任何Loading状态
  const hasAnyLoading = Object.values(loadingStates).some(Boolean) || globalLoading;

  return {
    loadingStates,
    globalLoading,
    hasAnyLoading,
    setLoading,
    getLoading,
    clearLoading,
    clearAllLoading,
    withLoading,
    withGlobalLoading,
  };
};

/**
 * 组合错误处理和Loading状态管理的Hook
 * 提供完整的异步操作状态管理解决方案
 */
export const useAsyncState = () => {
  const errorHandler = useErrorHandler();
  const loadingState = useLoadingState();

  /**
   * 安全的异步操作执行器
   * 自动处理Loading状态和错误处理
   * @param key - 操作的唯一标识
   * @param asyncFn - 异步函数
   * @param options - 配置选项
   */
  const executeAsync = useCallback(async <T>(
    key: string,
    asyncFn: () => Promise<T>,
    options?: {
      showError?: boolean;
      customErrorMessage?: string;
      maxRetries?: number;
      retryDelay?: number;
    }
  ): Promise<T | null> => {
    const {
      showError = true,
      customErrorMessage,
      maxRetries = 0,
      retryDelay = 1000
    } = options || {};

    try {
      errorHandler.clearError();
      
      if (maxRetries > 0) {
        return await loadingState.withLoading(key, () =>
          errorHandler.withRetry(asyncFn, maxRetries, retryDelay)
        );
      } else {
        return await loadingState.withLoading(key, asyncFn);
      }
    } catch (error) {
      errorHandler.handleError(error, showError, customErrorMessage);
      return null;
    }
  }, [errorHandler, loadingState]);

  return {
    ...errorHandler,
    ...loadingState,
    executeAsync,
  };
};